#include "imageloader.h"
#include "stitcher.h"
#include "commandlineoptions.h"
#include "boost/filesystem.hpp"
#include "boost/foreach.hpp"
#include <opencv/cxcore.h>
#include <opencv/cv.h>
#include "imageset.h"

using namespace std;
using namespace cshotel;
using namespace cv;
using namespace boost;
using namespace boost::filesystem;

ImageLoader::ImageLoader(const std::vector<std::string>& names) : fileNames(names) {}

shared_ptr<ImageSet> ImageLoader::loadImages() {
    dout("Loading images ..." << endl);
    
    shared_ptr<ImageSet> result(new ImageSet());

    // try to load all images
    int counter = 0;
    foreach(string s, fileNames) {
        dout("    loading image " << s << " ... " << endl);
        path filePath(s);
        if(!filePath.has_filename()) {
            dout("        not a filename, skipping" << endl);
            continue;
        }
        
        Mat image = imread(s.c_str());
        if(image.data == NULL) {
            dout("        could not read the file, skipping" << endl);
            continue;
        }
        
        dout("        scaling the image for matching ..." << endl); 
        double maximumDimension = CommandLineOptions::getInstance().getMaximumMatchingVersionImageSize();
        double scaleFactorX = maximumDimension / image.cols;
        double scaleFactorY = maximumDimension / image.rows;
        double scaleFactor = min(1.0, min(scaleFactorX, scaleFactorY));
        string matchingVersionFileName = getMatchingVersionFileName(filePath.filename());
        dout("        scale factor = " << scaleFactor << endl);
        dout("        file name: " << matchingVersionFileName << endl);
        Mat scaledImage;
        
        // for each image, we also generate a scaled down version
        // for feature extraction
        resize(image, scaledImage, Size(0, 0), scaleFactor, scaleFactor, INTER_AREA);
        imwrite(matchingVersionFileName.c_str(), scaledImage);
        
        shared_ptr<InputImage> newImage(new InputImage(s, Size2i(image.cols, image.rows), matchingVersionFileName, scaleFactor, counter));
        result->addImage(newImage);
        dout("        done, new image has ID " << counter << endl);
        ++counter;
    }
    
    return result;
}

string ImageLoader::getMatchingVersionFileName(const string& fileName) {
    string prefix = CommandLineOptions::getInstance().getWorkingDirectory();
    int dotIndex = fileName.rfind('.');
    if(dotIndex == string::npos) {
        return prefix + fileName + "_resized";
    }
    return prefix + fileName.substr(0, dotIndex) + "_resized" + fileName.substr(dotIndex, fileName.size() - dotIndex);
}
